<template>
  <div class="custom-select">
    <el-select
      ref="customSelect"
      v-model="currentCode"
      :placeholder="placeholder"
      :clearable="clearable"
      :remote="remote"
      :filterable="filterable"
      :multiple="multiple"
      :remote-method="remoteMethod"
      :loading="loading"
      @change="customSelectChange"
      @focus="focusChange"
      @visible-change="isShowSelectOptions"
    >
      <el-option
        v-for="(list, index) in selectOptions"
        :key="index"
        :label="list[bindName]"
        :value="list[bindValue]"
      />
    </el-select>
  </div>
</template>

<script>
import request from '@/utils/request'
export default {
  props: {
    placeholder: {
      type: String,
      default: '请输入'
    },
    clearable: {
      type: Boolean,
      default: true
    },
    filterable: {
      type: Boolean,
      default: true
    },
    // 是否启动远程搜索
    remote: {
      type: Boolean,
      default: false
    },
    // 请求Url
    url: {
      type: String,
      default: ''
    },
    // 是否加载时请求数据
    immediate: {
      type: Boolean,
      default: true
    },
    // 请求方式
    methodType: {
      type: String,
      default: 'GET'
    },
    // 是否包含翻页请求
    isPage: {
      type: Boolean,
      default: false
    },
    // 请求参数
    params: {
      type: Object,
      default() {
        return {}
      }
    },
    // 参数传递方式
    paramsType: {
      type: String,
      default: 'path'
    },
    // 搜索字段
    findField: {
      type: String,
      default: ''
    },
    // 是否多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 回显或select value值
    echoValue: {
      type: [String, Number, Array],
      default: ''
    },
    echoName: {
      type: [String, Number, Array],
      default: ''
    },
    // 绑定的Label名称
    bindName: {
      type: [String, Array],
      default: ''
    },
    // 绑定的Label值
    bindValue: {
      type: [String, Array],
      default: ''
    },
    // 是否开启取额外参数，当 emit为空时，取全部OBJ数据
    isEmit: {
      type: Boolean,
      default: false
    },
    // 所取值集合，改参数需开启 isEmit
    emitArr: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      loading: false,
      queryString: '',
      selectOptions: [],
      currentCode: ''
    }
  },
  watch: {
    echoValue: {
      handler(newVal, oldVal) {
        if (newVal !== oldVal) {
          this.currentCode = newVal
        }
      },
      immediate: false,
      deep: true
    },
    // echoName: {
    //   handler(nv, ov) {
    //     if (nv !== ov) {
    //     }
    //   },
    //   immediate: false,
    //   deep: true
    // },
    params: {
      handler(newVal, oldVal) {
        if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
          this.$emit('update:echoValue', '')
          this.$emit('update:echoName', '')
          this.$set(this, 'queryString', '')
          this.selectOptions = []
          this.getCustomPickerInfo()
        }
      },
      immediate: false,
      deep: true
    },
    url: {
      handler(nv, ov) {
        if (nv !== ov) {
          if (this.selectOptions.length) {
            this.$emit('update:echoValue', '')
            this.$emit('update:echoName', '')
          }
          this.$set(this, 'queryString', '')
          this.selectOptions = []
          this.getCustomPickerInfo()
        }
      },
      immediate: false,
      deep: true
    }
  },
  created() {
  },
  mounted() {
    if (this.url === '') return
    if (this.immediate) {
      this.getCustomPickerInfo()
    }
  },
  methods: {
    // 是否显示下拉框
    isShowSelectOptions(isShowSelectOptions) {
      if (!isShowSelectOptions) this.$refs.customSelect.blur()
    },
    // 服务端搜索
    remoteMethod(query) {
      this.loading = true
      this.queryString = query
      this.$nextTick(() => {
        this.getCustomPickerInfo()
      })
    },
    // 获取数据
    getCustomPickerInfo() {
      const paramsType = this.paramsType
      let params = {}
      const searchParams = {}
      const paramsObj = new FormData()
      if (this.isPage) {
        paramsObj.append('rows', 20)
        paramsObj.append('page', 1)
      }
      switch (paramsType) {
        case 'query':
          Object.keys(this.params).forEach(k => {
            if (this.params[k]) searchParams[k] = this.params[k]
          })
          if (this.queryString) searchParams[this.findField ? this.findField : this.bindName] = this.queryString
          params = {
            url: this.url,
            method: this.methodType,
            params: searchParams
          }
          break
        case 'path':
          Object.keys(this.params).forEach(k => {
            if (this.params[k]) searchParams[k] = this.params[k]
          })
          if (this.queryString) searchParams[this.findField ? this.findField : this.bindValue] = this.queryString
          params = {
            url: this.url,
            method: this.methodType,
            params: searchParams
          }
          break
        case 'formData':
          params = {
            url: this.url,
            method: this.methodType,
            data: paramsObj
          }
          break
        default:
          break
      }
      this.selectOptions = []
      request(params).then(response => {
        if (response.success === 1) {
          let data = []
          if (typeof response.data === 'object' && response.data.hasOwnProperty('records')) {
            data = response.data.records
          } else {
            data = response.data
          }
          if (data) {
            // const obj = data.find(list => {
            //   return list[this.bindValue] === this.currentCode
            // })
            // if (obj === '' || obj === undefined || obj === 'undefined') {
            //   if (this.echoValue && this.echoName) {
            //     const addObj = {}
            //     addObj[this.bindValue] = this.echoValue
            //     addObj[this.bindName] = this.echoName
            //     data.unshift(addObj)
            //   }
            // }
            this.selectOptions = data
          }
          this.loading = false
        } else {
          this.selectOptions = []
          this.loading = false
        }
      }, () => {
        this.selectOptions = []
        this.loading = false
      })
    },
    setOption(newVal) {
      let obj = {}
      obj = this.selectOptions.find(list => {
        return list[this.bindValue] === newVal
      })
      if (obj === '' || obj === undefined || obj === 'undefined') {
        if (this.echoValue && this.echoName) {
          const addObj = {}
          addObj[this.bindValue] = this.echoValue
          addObj[this.bindName] = this.echoName
          this.selectOptions.unshift(addObj)
        }
      }
    },
    // 获取焦点时执行
    focusChange() {},
    // 下拉框值改变时
    customSelectChange(val) {
      this.$set(this, 'queryString', '') // 重置搜索条件
      // 判断选择中是否为空
      if (val === '' || (Array.isArray(val) && val.length === 0)) {
        this.queryString = val
        if (Array.isArray(this.selectOptions) && this.selectOptions.length) {
          const k = this.selectOptions[0]
          if (typeof k === 'object' && Object.keys(k).length) {
            Object.keys(k).forEach(key => {
              this.$emit(`update:${key}`, '')
            })
          }
        }
        this.$emit('update:echoValue', '')
        this.$emit('update:echoName', '')
        this.selectOptions = []
        if (this.immediate) {
          this.getCustomPickerInfo()
        }
        return
      }
      // 多选
      if (this.multiple) {
        if (Array.isArray(val) && val.length) {
          const selectArr = val.map(item => {
            const obj = this.selectOptions.find(list => {
              return list[this.bindValue] === item
            })
            return obj
          })
          if (selectArr.length) {
            const keyArr = Object.keys(selectArr[0])
            const obj = {}
            selectArr.forEach(list => {
              keyArr.forEach(k => {
                obj[k] ? obj[k] += `,${list[k]}` : obj[k] = `${list[k]}`
              })
            })
            if (typeof obj === 'object' && Object.keys(obj).length) {
              if (this.isEmit) {
                if (Array.isArray(this.emitArr) && this.emitArr.length) {
                  this.emitArr.forEach(k => {
                    if (k === 'id') {
                      this.$emit(`update:${k}s`, obj[k])
                    } else {
                      this.$emit(`update:${k}`, obj[k])
                    }
                  })
                } else {
                  Object.keys(obj).forEach(key => {
                    if (key === 'id') {
                      this.$emit(`update:${key}s`, obj[key])
                    } else {
                      this.$emit(`update:${key}`, obj[key])
                    }
                  })
                }
              }
              this.$emit('update:echoValue', obj[this.bindValue])
              this.$emit('update:echoName', obj[this.bindName])
            }
          }
        }
      }
      // 下拉框单选
      if (!this.multiple) {
        const obj = this.selectOptions.find(list => {
          return list[this.bindValue] === val
        })
        if (typeof obj === 'object' && Object.keys(obj).length) {
          if (this.isEmit) {
            if (Array.isArray(this.emitArr) && this.emitArr.length) {
              this.emitArr.forEach(k => {
                if (k === 'id') {
                  this.$emit(`update:${k}s`, obj[k])
                } else {
                  this.$emit(`update:${k}`, obj[k])
                }
              })
            } else {
              Object.keys(obj).forEach(key => {
                if (key === 'id') {
                  this.$emit(`update:${key}s`, obj[key])
                } else {
                  this.$emit(`update:${key}`, obj[key])
                }
              })
            }
          }
          this.$emit('update:echoValue', obj[this.bindValue])
          this.$emit('update:echoName', obj[this.bindName])
        }
      }
    }
  }
}
</script>

<style lang="less" scoped>
.custom-select {
  /deep/ .el-select {
    width: 100%;
  }
}
</style>
